package com.ztgf.order.service.pay;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.ztgf.common.constant.Result;
import com.ztgf.common.enums.CodeEnum;
import com.ztgf.common.utils.StrUtils;
import com.ztgf.common.vo.UserVO;
import com.ztgf.dubbo.exception.ServiceException;
import com.ztgf.order.mapper.*;
import com.ztgf.order.models.bo.pay.PayOrderLogBO;
import com.ztgf.order.models.bo.pay.PayOrderSaveBO;
import com.ztgf.order.models.dto.*;
import com.ztgf.order.models.dto.pay.PayOrderLogDTO;
import com.ztgf.order.models.service.IOrderPayRelationService;
import com.ztgf.order.models.service.IOrderPaymentTypeService;
import com.ztgf.order.models.service.common.ICommonService;
import com.ztgf.order.models.service.pay.IPayLogisticsService;
import com.ztgf.order.models.service.pay.IPayOrderLogService;
import com.ztgf.order.models.service.pay.IPayOrderService;
import com.ztgf.order.models.service.pay.IPayService;
import com.ztgf.order.models.vo.pay.PayOrderLogVO;
import com.ztgf.order.models.vo.pay.PayOrderMoneyVO;
import com.ztgf.order.models.vo.pay.PayOrderVO;
import com.ztgf.pay.models.dto.PayOrderDTO;
import com.ztgf.shopping.models.dto.shop.ShopEarnestMoneyDTO;
import com.ztgf.shopping.models.dto.shop.ShopInfoDTO;
import com.ztgf.shopping.models.service.shop.IShopEarnestMoneyService;
import com.ztgf.shopping.models.service.shop.IShopInfoService;
import com.ztgf.sms.models.dto.sms.SmsInfoDTO;
import com.ztgf.sms.models.service.ISmsInfoService;
import com.ztgf.sys.models.service.ISessionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;


import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

/**
 * @Description:
 * @Author: mxli
 * @Date: 2021-06-16 02:10
 **/
@DubboService
@Slf4j
public class PayServiceImpl implements IPayService {

    @Autowired
    @Lazy
    private IPayOrderLogService payOrderLogService;

    @DubboReference
    private IShopInfoService shopInfoService;

    @DubboReference
    private ISmsInfoService smsInfoService;

    @DubboReference
    private IShopEarnestMoneyService shopEarnestMoneyService;

    @Autowired
    private ICommonService commonService;

    @Resource
    private OrderInfoMapper orderInfoMapper;
    @Resource
    private OrderStatusMapper orderStatusMapper;
    @Resource
    private OrderPayRelationMapper orderPayRelationMapper;
    @Resource
    private OrderReturnCommodityMapper orderReturnCommodityMapper;

    @DubboReference
    private ISessionService sessionService;
    @Autowired
    private IPayOrderService payOrderService;
    @Autowired
    private IPayLogisticsService payLogisticsService;
    @Autowired
    private IPayNotifyService payNotifyService;

    @Autowired
    private IOrderPayRelationService orderPayRelationService;

    @Autowired
    private IOrderPaymentTypeService orderPaymentTypeService;

    @Override
    public Result<PayOrderMoneyVO> getPayMoney(String ids, Integer type, boolean isCheckToken) {
        //金额类型：0订单金额，1佣金、2店铺保证金、3年费、4采购申请平台砍价、5砍价手续费
        if(StrUtils.isEmpty(ids) || type == null){
            return new Result<>(CodeEnum.FAIL_100002);
        }

        Long userId = null;
        String userName = "";
        Long shopId = null;
        ShopInfoDTO shopInfoDTO = null;
        if(isCheckToken){

            UserVO userVO = sessionService.getUserVO();
            userId = userVO.getId();
            userName = userVO.getName();

            shopInfoDTO = shopInfoService.getByUserId(userId);
            if(shopInfoDTO == null){
                return new Result(CodeEnum.FAIL_100053);
            }
            shopId = shopInfoDTO.getId();
        }


        PayOrderMoneyVO moneyVO = new PayOrderMoneyVO();
        if(type == 0){
            payOrderLogService.getOrderInfo(ids, moneyVO, shopId);
        } else if(type == 1){//佣金
            payOrderLogService.getCommissionMoney(ids, moneyVO, shopId);
        } else if(type == 2){//店铺保证金
            payOrderLogService.getMargin(ids, moneyVO);
        } else if(type == 3){//年费
            payOrderLogService.getAnnualFee(ids, moneyVO);
        } else if(type == 4){//采购申请平台砍价
            payOrderLogService.getPurchaseBargain(ids, moneyVO, shopId);
            if(shopInfoDTO != null){
                Integer purchaseFeeMoneyFreeTimes = shopInfoDTO.getPurchaseFeeMoneyFreeTimes();
                if(purchaseFeeMoneyFreeTimes > 0){
                    moneyVO.setMoney(BigDecimal.ZERO);
                    moneyVO.setPurchaseFeeMoneyFreeTimes(purchaseFeeMoneyFreeTimes);
                }
            }
        } else if(type == 5){//砍价手续费
            payOrderLogService.getPurchaseFeeMoneyScalePrice(ids, moneyVO, shopId);
        } else if(type == 15){//15缴纳物流保证金
            payOrderLogService.getLogisticsMargin(shopId, moneyVO);
        } else if(type == 18){//18支付物流账单
            payOrderLogService.getLogisticsBill(ids, shopId, moneyVO);
        }

        return new Result<>(moneyVO);
    }

    /**
     * 支付
     * @param bo
     * @param isCheckToken 是否效验token
     * @return
     */
    @Override
    public Result<PayOrderVO> savePay(PayOrderSaveBO bo, boolean isCheckToken) {
        log.info("------------支付-savePay------------>>>>" + JSON.toJSONString(bo));
        if(bo.getPayType() == null || bo.getType() == null || StrUtils.isEmpty(bo.getIds())){
            return new Result<>(CodeEnum.FAIL_100002);
        }
        Long userId = null;
        String userName = "";
        Long shopId = null;
        ShopInfoDTO shopInfoDTO = null;
        UserVO userVO = sessionService.getUserVO();
        if(userVO != null){
            userId = userVO.getId();
            userName = userVO.getName();
            if(userVO.getType() == 0){
                shopInfoDTO = shopInfoService.getByUserId(userId);
                if(shopInfoDTO == null){
                    return new Result(CodeEnum.FAIL_100053);
                }
                shopId = shopInfoDTO.getId();
            }
        }

        if(bo.getPayType() == 0){
            if(isCheckToken){
                if(StrUtils.isEmpty(bo.getVerifyCode())){
                    return new Result<>(CodeEnum.FAIL_100002);
                }

                //验证验证码
                Wrapper wrapper = new EntityWrapper();
                wrapper.eq("shop_id", shopId);
                wrapper.eq("captcha_type", 4);
                wrapper.eq("is_verify", 0);
                wrapper.orderBy("id", false);
                SmsInfoDTO dto = smsInfoService.selectOne(wrapper);
                if(dto == null){
                    return new Result<>(CodeEnum.FAIL_Login_1004);
                }
                dto.setIsVerify(1);
                wrapper = new EntityWrapper();
                wrapper.eq("id", dto.getId());
                wrapper.eq("is_verify", 0);
                if(!smsInfoService.update(dto, wrapper)){
                    return new Result<>(CodeEnum.FAIL_Login_1004);
                }
                if(!bo.getVerifyCode().equalsIgnoreCase(dto.getCode())){
                    return new Result<>(CodeEnum.FAIL_Login_1004);
                }
            }
        } else if(bo.getPayType() == 1){
            if(bo.getBankId() == null || StrUtils.isEmpty(bo.getBankName())){
                return new Result<>(CodeEnum.FAIL_100002);
            }
        }

        PayOrderVO payOrderVO = new PayOrderVO();
        payOrderVO.setType(bo.getType());
        try{
            if(bo.getType() == 0){
                payOrderService.savePayOrderInfo(bo, payOrderVO, shopId, userId, userName);
            } else if(bo.getType() == 1){//佣金
                payOrderService.savePayCommissionMoney(bo, payOrderVO, userId, userName);
            } else if(bo.getType() == 2){//店铺保证金
                payOrderService.savePayMargin(bo, payOrderVO, shopId, userId, userName);
            } else if(bo.getType() == 3){//年费
                payOrderService.savePayAnnualFee(bo, payOrderVO, userId, userName);
            } else if(bo.getType() == 4){//采购申请平台砍价
                if(shopInfoDTO != null && shopInfoDTO.getPurchaseFeeMoneyFreeTimes() > 0){
                    return new Result<>(CodeEnum.FAIL_100070);
                }
                payOrderService.savePayPurchaseBargain(bo, payOrderVO, shopId, userId, userName);
            } else if(bo.getType() == 5){//砍价手续费
                payOrderService.savePayPurchaseFeeMoneyScalePrice(bo, payOrderVO, shopId, userId, userName);
            } else if(bo.getType() == 6){//重复支付
            } else if(bo.getType() == 7){//售后订单退款
                saveAfterSalePayBack(bo, payOrderVO, userId, userName);
            } else if(bo.getType() == 9){//扣除保证金
                payOrderService.saveDeductMargin(bo, payOrderVO, userId, userName);
            } else if(bo.getType() == 10){//取消订单退款
                saveCancelPayBack(bo, payOrderVO, userId, userName);
            } else if(bo.getType() == 13){//订单签收
                commonService.saveReceiveMoney(bo, payOrderVO, userId, userName);
            } else if(bo.getType() == 15){//15缴纳物流保证金
                payLogisticsService.saveLogisticsPayMargin(bo, payOrderVO, shopId, userId, userName);
            } else if(bo.getType() == 16){//16解冻物流保证金
                payLogisticsService.saveLogisticsUnfreezeMarginMoney(Long.parseLong(bo.getIds()), bo.getMoney(), userId, userName);
            } else if(bo.getType() == 17){//17扣除物流保证金
                payLogisticsService.saveLogisticsDeductMargin(Long.parseLong(bo.getIds()), bo.getMoney(), bo.getNotes(), userId, userName);
            } else if(bo.getType() == 18){// 18支付物流账单
                payLogisticsService.saveLogisticsPayBillMoney(bo, payOrderVO, shopId, userId, userName);
            } else if(bo.getType() == 19){// 19退款佣金
                payOrderService.saveRefundCommissionMoney(bo, payOrderVO, userId, userName);
            } else {
                return new Result<>(CodeEnum.FAIL_100002);
            }
        } catch (ServiceException e){
            log.error("--savePay ServiceException 支付错误--" + JSON.toJSONString(bo), e);
            return new Result<>(e.getCode(), e.getMessage());
        } catch (RuntimeException e){
            log.error("--savePay RuntimeException 支付错误--" + JSON.toJSONString(bo), e);
            return new Result<>(CodeEnum.FAIL.getCode(), "支付错误");
        } catch (Exception e){
            log.error("--savePay Exception 支付错误--" + JSON.toJSONString(bo), e);
            return new Result<>(CodeEnum.FAIL.getCode(), "支付错误");
        }
        return new Result<>(payOrderVO);
    }

    @Override
    public Result saveSellContactSuccess(Long orderId) {
        return commonService.saveSellContactSuccess(orderId);
    }

    @Override
    public Result saveUnfreezeMarginMoney(Long shopId, BigDecimal money, String notes) {
        if(shopId == null || money == null || money.compareTo(BigDecimal.ZERO) <= 0){
            return new Result(CodeEnum.FAIL_100002);
        }

        ShopEarnestMoneyDTO moneyDTO = shopEarnestMoneyService.getByShopId(shopId);
        if(moneyDTO == null){
            return new Result(CodeEnum.FAIL_100002);
        }
        if(moneyDTO.getPaid().compareTo(money) < 0){
            return new Result(CodeEnum.FAIL_200028);
        }

        UserVO userVO = sessionService.getUserVO();
        Long userId = userVO.getId();
        String userName = userVO.getName();

        try{
            payOrderService.saveUnfreezeMarginMoney(moneyDTO, shopId, money, userId, userName, notes);
        } catch (ServiceException e){
            log.error("解冻保证金错误ServiceException",e);
            return new Result(e.getCode(), e.getMessage());
        } catch (RuntimeException e){
            log.error("解冻保证金错误RuntimeException is error ", e);
            return new Result(CodeEnum.FAIL, e.getMessage());
        } catch (Exception e){
            log.error("解冻保证金错误Exception is error ", e);
            return new Result(CodeEnum.FAIL, e.getMessage());
        }
        return new Result();
    }

    @Override
    public Page<PayOrderLogVO> queryPagePayOrderLog(PayOrderLogBO bo) {
        return payOrderLogService.queryPagePayOrderLog(bo);
    }

    @Override
    public BigDecimal querySumDeductMarginMoney(Long shopId, int type) {
        return payOrderLogService.querySumDeductMarginMoney(shopId, type);
    }

    @Override
    public void saveOrderPaySuccess(PayOrderDTO orderDTO, PayOrderLogDTO logDTO) {
        payNotifyService.saveOrder(orderDTO, logDTO);
    }

    /**
     * 售后订单退款
     * @param bo
     * @param userId
     * @param userName
     */
    public void saveAfterSalePayBack(PayOrderSaveBO bo, PayOrderVO payOrderVO, Long userId, String userName){

        OrderReturnCommodityDTO orderReturnCommodityDTO = orderReturnCommodityMapper.selectById(Long.parseLong(bo.getIds()));
        if (orderReturnCommodityDTO == null) {
            throw new ServiceException(CodeEnum.FAIL_100002);
        }

        if(orderReturnCommodityDTO.getAfterSalesState() != 3){
            throw new ServiceException(CodeEnum.FAIL_100002);
        }

        //退款砍价服务费
        if(orderReturnCommodityDTO.getPurchaseFeeMoneyScaleBackPrice().compareTo(BigDecimal.ZERO) > 0 && orderReturnCommodityDTO.getPurchaseFeeMoneyScalePriceBackStatus() != 2){
            try{
                payOrderService.saveRefundPurchaseFeeMoney(bo, orderReturnCommodityDTO, payOrderVO, userId, userName);
            } catch (ServiceException e){
                log.error("售后订单砍价服务费退款ServiceException saveRefundPurchaseFeeMoney is null--->>>"  + JSON.toJSONString(orderReturnCommodityDTO), e);
            } catch (RuntimeException e){
                log.error("售后订单砍价服务费退款RuntimeException saveRefundPurchaseFeeMoney is null--->>>"  + JSON.toJSONString(orderReturnCommodityDTO), e);
            } catch (Exception e){
                log.error("售后订单砍价服务费退款Exception saveRefundPurchaseFeeMoney is null--->>>"  + JSON.toJSONString(orderReturnCommodityDTO), e);
            }
        }

        if(orderReturnCommodityDTO.getRefundPrice().compareTo(BigDecimal.ZERO) > 0 && orderReturnCommodityDTO.getRefundStatus() != 2){

            OrderInfoDTO orderInfoDTO = orderInfoMapper.selectById(orderReturnCommodityDTO.getOrderId());
            if(orderInfoDTO == null){
                log.error("售后订单退款saveAfterSalePayBack orderInfoDTO is null--->>>"  + JSON.toJSONString(orderReturnCommodityDTO));
                throw new ServiceException(CodeEnum.FAIL_100002);
            }

            try{
                payOrderService.saveRefundMoney(bo, payOrderVO, orderReturnCommodityDTO, userId, userName, orderInfoDTO.getOrderNo());
            } catch (ServiceException e){
                log.error("售后订单分两次退款ServiceException saveRefundMoney is null--->>>"  + JSON.toJSONString(orderReturnCommodityDTO), e);
            } catch (RuntimeException e){
                log.error("售后订单分两次退款RuntimeException saveRefundMoney is null--->>>"  + JSON.toJSONString(orderInfoDTO), e);
            } catch (Exception e){
                log.error("售后订单分两次退款Exception saveRefundMoney is null--->>>"  + JSON.toJSONString(orderInfoDTO), e);
            }
        }
    }


    /**
     * 取消订单退款
     * @param bo
     * @param userId
     * @param userName
     */
    public void saveCancelPayBack(PayOrderSaveBO bo, PayOrderVO payOrderVO, Long userId, String userName){

        OrderInfoDTO orderInfoDTO = orderInfoMapper.selectById(Long.parseLong(bo.getIds()));
        OrderStatusDTO orderStatusDTO = new OrderStatusDTO();
        orderStatusDTO.setOrderId(orderInfoDTO.getId());
        orderStatusDTO = orderStatusMapper.selectOne(orderStatusDTO);
        if(orderInfoDTO == null || orderStatusDTO == null){
            throw new ServiceException(CodeEnum.FAIL_100002);
        }

        if(!(orderStatusDTO.getOrderState() == 6 || orderStatusDTO.getOrderState() == 7)){
            throw new ServiceException(CodeEnum.FAIL_100002);
        }

        //退款佣金
        try{
            if(orderStatusDTO.getCommissionMoneyPayStatus() == 2 && orderInfoDTO.getLastCommissionMoney().compareTo(BigDecimal.ZERO) > 0){
                PayOrderSaveBO payOrderSaveBO = new PayOrderSaveBO();
                payOrderSaveBO.setIds(orderInfoDTO.getId().toString());
                payOrderSaveBO.setPayType(0);
                payOrderSaveBO.setType(19);
                payOrderSaveBO.setMoney(orderInfoDTO.getLastCommissionMoney());
                payOrderService.saveRefundCommissionMoney(payOrderSaveBO, payOrderVO, userId, userName);
            }
        } catch (ServiceException e){
            log.error("取消订单佣金退款ServiceException saveCancelRefundPurchaseFeeMoneyScalePrice is null--->>>"  + JSON.toJSONString(orderInfoDTO), e);
        } catch (RuntimeException e){
            log.error("取消订单佣金退款RuntimeException saveCancelRefundPurchaseFeeMoneyScalePrice is null--->>>"  + JSON.toJSONString(orderInfoDTO), e);
        } catch (Exception e){
            log.error("取消订单佣金退款Exception saveCancelRefundPurchaseFeeMoneyScalePrice is null--->>>"  + JSON.toJSONString(orderInfoDTO), e);

        }

        try{
            if(orderInfoDTO.getPurchaseFeeMoneyScalePrice().compareTo(BigDecimal.ZERO) > 0 && orderInfoDTO.getPurchaseFeeMoneyScalePriceStatus() == 2 && orderInfoDTO.getPurchaseFeeMoneyScalePriceBackStatus() != 2){
                payOrderService.saveCancelRefundPurchaseFeeMoneyScalePrice(bo, orderInfoDTO, payOrderVO, userId, userName);
            }
        } catch (ServiceException e){
            log.error("取消订单砍价手续费退款ServiceException saveCancelRefundPurchaseFeeMoneyScalePrice is null--->>>"  + JSON.toJSONString(orderInfoDTO), e);
        } catch (RuntimeException e){
            log.error("取消订单砍价手续费退款RuntimeException saveCancelRefundPurchaseFeeMoneyScalePrice is null--->>>"  + JSON.toJSONString(orderInfoDTO), e);
        } catch (Exception e){
            log.error("取消订单砍价手续费退款Exception saveCancelRefundPurchaseFeeMoneyScalePrice is null--->>>"  + JSON.toJSONString(orderInfoDTO), e);

        }

        try{

            OrderPaymentTypeDTO typeDTO = orderPaymentTypeService.getOrderPaymentByOrderIdAndType(orderInfoDTO.getId(), 1,2);

            // 业务标示:
            // 余额支付：A00 普通订单支付,B00 收款方收款成功后，再冻结资金, B01 付款方解冻资金后，再支付给收款方；
            // 网银支付： A00 入金并支付 B00 收款方收款成功后，再 冻结资金
            String trsFlag = "B01";
            if(typeDTO != null){
                List<OrderPayRelationDTO> relationDTOList = orderPayRelationService.getByOrderId(orderInfoDTO.getId());
                trsFlag = "A00";
                if(relationDTOList != null && relationDTOList.size() > 0){
                    for(OrderPayRelationDTO orderPayRelationDTO : relationDTOList){
                        try {
                            payOrderService.savePayCancelRefundMoney(bo, orderInfoDTO, payOrderVO, userId, userName, orderPayRelationDTO, trsFlag);
                        } catch (ServiceException e){
                            log.error("取消订单退款ServiceException  saveCancelRefundMoney foreach is null--->>>"  + JSON.toJSONString(orderInfoDTO), e);
                        } catch (RuntimeException e){
                            log.error("取消订单退款RuntimeException saveCancelRefundMoney foreach is null--->>>"  + JSON.toJSONString(orderInfoDTO), e);
                        } catch (Exception e){
                            log.error("取消订单退款Exception saveCancelRefundMoney foreach is null--->>>"  + JSON.toJSONString(orderInfoDTO), e);
                        }
                    }
                }
            } else {
                OrderPayRelationDTO orderPayRelationDTO = orderPayRelationService.getByOrderIdAndPeriods(orderInfoDTO.getId(), 1);//一期
                payOrderService.savePayCancelRefundMoney(bo, orderInfoDTO, payOrderVO, userId, userName, orderPayRelationDTO, trsFlag);
            }

        } catch (ServiceException e){
            log.error("取消订单退款ServiceException  saveCancelRefundMoney is null--->>>"  + JSON.toJSONString(orderInfoDTO), e);
        } catch (RuntimeException e){
            log.error("取消订单退款RuntimeException saveCancelRefundMoney is null--->>>"  + JSON.toJSONString(orderInfoDTO), e);
        } catch (Exception e){
            log.error("取消订单退款Exception saveCancelRefundMoney is null--->>>"  + JSON.toJSONString(orderInfoDTO), e);
        }
    }
}
